knitr::opts_chunk$set(echo = TRUE)
library(kableExtra)
library(mice) #IMP
##
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
##
## filter
## The following objects are masked from 'package:base':
##
## cbind, rbind
library(knitr)
library(FactoMineR)
library(factoextra)
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(corrplot)
## corrplot 0.92 loaded
library(arules) #discretize
## Loading required package: Matrix
##
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
##
## abbreviate, write
library(clValid)
## Loading required package: cluster
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:arules':
##
## intersect, recode, setdiff, setequal, union
## The following object is masked from 'package:kableExtra':
##
## group_rows
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
library(readr)
library(Rtsne)
library(clustMixType)
library(fpc)
library(arulesViz)
library(dplyr)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v tibble 3.1.6 v stringr 1.4.0
## v tidyr 1.2.0 v forcats 0.5.1
## v purrr 0.3.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x tidyr::expand() masks Matrix::expand()
## x dplyr::filter() masks mice::filter(), stats::filter()
## x dplyr::group_rows() masks kableExtra::group_rows()
## x dplyr::lag() masks stats::lag()
## x tidyr::pack() masks Matrix::pack()
## x dplyr::recode() masks arules::recode()
## x tidyr::unpack() masks Matrix::unpack()
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
data = read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\vendImp.csv", sep=';', as.is = FALSE)
datosA= read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\venta_pisos.csv", sep=';', as.is = FALSE, encoding='UTF-8')
dataCluster = read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\dataCluster.csv", sep=';', as.is = FALSE)
vend = read.csv("C:\\Users\\EvaCantin\\Desktop\\UNI\\SEGUNDO\\PROYECTO\\Clustering\\vend.csv", sep=';', as.is = FALSE)
Las reglas de asociación son un método útil para la búsqueda de patrones dentro un conjunto de transacciones aplicadas a variables categorícas, generalmente binarias. Para ello, a parte de trabajar con las variables binarias que hay en la base de datos, también se realiza una categorización de variables numéricas, con el fin de tener más información de los patrones de los inmuebles.
# Categorizamos los baños, las habitaciones, la variación del precio y los metros cuadrados
data$baños_cat=cut(data$baños, breaks = c(0,1,10),labels=c("1","+1"),include.lowest = TRUE)
data$hab_cat=cut(data$habitaciones, breaks = c(0,3,10),labels=c("1-3","+3"), include.lowest = TRUE)
data$var_precio=cut(data$variacion_precio,
breaks = c(-999999,-0.001,0.001,999999),
labels=c("baja",'igual',"sube"),
include.lowest = TRUE)
data$m2_cat=cut(data$variacion_precio, breaks = c(0,70,86,99,118,148,750),include.lowest = TRUE)
# Creamos un data frame con las variables elegidas
sub_data=cbind(data[,4:7],a_reformar=data[,9],distrito=data[,15],data[,17:23],vistas=data[,25],data[,30:32])
data1<-data.frame(lapply(sub_data,factor))
data1=cbind(data1,planta_cat=data$planta_cat,tipo_vendedor=as.factor(data$tipo_vendedor))
# Para poder trabajar con la librería Arules convertimos el data frame a trasacción
data2 <- as(data1, "transactions")
freq_items=itemFrequency(x = data2, type = "absolute")
kable(freq_items %>% sort(decreasing = TRUE) %>% head(20))
| x | |
|---|---|
| vistas=1 | 2107 |
| tipo_vendedor=2 | 2100 |
| jardin=0 | 2080 |
| piscina=0 | 2073 |
| var_precio=igual | 2073 |
| a_reformar=0 | 1976 |
| trastero=0 | 1903 |
| garaje.incluido=0 | 1766 |
| acceso.adaptado=0 | 1698 |
| ascensor=1 | 1685 |
| terraza=0 | 1586 |
| hab_cat=1-3 | 1556 |
| balcon=0 | 1282 |
| baños_cat=+1 | 1242 |
| armarios.empotrados=1 | 1225 |
| calefaccion=1 | 1218 |
| aire.acondicionado=1 | 1183 |
| aire.acondicionado=0 | 1038 |
| calefaccion=0 | 1003 |
| armarios.empotrados=0 | 996 |
# Se utiliza un soporte alto porque se busca las características más frecuentes
itemsets=apriori(data2,parameter = list(support = 0.1, target = "frequent itemset", minlen=2))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## NA 0.1 1 none FALSE TRUE 5 0.1 2
## maxlen target ext
## 10 frequent itemsets TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 222
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[57 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [34 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(support = 0.1, target = "frequent
## itemset", : Mining stopped (maxlen reached). Only patterns up to a length of 10
## returned!
## done [0.91s].
## sorting transactions ... done [0.00s].
## writing ... [187260 set(s)] done [0.06s].
## creating S4 object ... done [0.11s].
top_15_itemsets=sort(itemsets, by = "support", decreasing = TRUE)[1:15]
kable(inspect(top_15_itemsets))
## items support count
## [1] {jardin=0, piscina=0} 0.9122017 2026
## [2] {vistas=1, tipo_vendedor=2} 0.8977938 1994
## [3] {jardin=0, tipo_vendedor=2} 0.8910401 1979
## [4] {jardin=0, vistas=1} 0.8869878 1970
## [5] {vistas=1, var_precio=igual} 0.8851869 1966
## [6] {piscina=0, tipo_vendedor=2} 0.8851869 1966
## [7] {piscina=0, vistas=1} 0.8838361 1963
## [8] {var_precio=igual, tipo_vendedor=2} 0.8824854 1960
## [9] {jardin=0, var_precio=igual} 0.8716794 1936
## [10] {piscina=0, var_precio=igual} 0.8680774 1928
## [11] {jardin=0, piscina=0, tipo_vendedor=2} 0.8676272 1927
## [12] {jardin=0, piscina=0, vistas=1} 0.8631247 1917
## [13] {jardin=0, piscina=0, var_precio=igual} 0.8482665 1884
## [14] {a_reformar=0, vistas=1} 0.8451148 1877
## [15] {jardin=0, vistas=1, tipo_vendedor=2} 0.8446646 1876
| items | support | count | |
|---|---|---|---|
| [1] | {jardin=0, piscina=0} | 0.9122017 | 2026 |
| [2] | {vistas=1, tipo_vendedor=2} | 0.8977938 | 1994 |
| [3] | {jardin=0, tipo_vendedor=2} | 0.8910401 | 1979 |
| [4] | {jardin=0, vistas=1} | 0.8869878 | 1970 |
| [5] | {vistas=1, var_precio=igual} | 0.8851869 | 1966 |
| [6] | {piscina=0, tipo_vendedor=2} | 0.8851869 | 1966 |
| [7] | {piscina=0, vistas=1} | 0.8838361 | 1963 |
| [8] | {var_precio=igual, tipo_vendedor=2} | 0.8824854 | 1960 |
| [9] | {jardin=0, var_precio=igual} | 0.8716794 | 1936 |
| [10] | {piscina=0, var_precio=igual} | 0.8680774 | 1928 |
| [11] | {jardin=0, piscina=0, tipo_vendedor=2} | 0.8676272 | 1927 |
| [12] | {jardin=0, piscina=0, vistas=1} | 0.8631247 | 1917 |
| [13] | {jardin=0, piscina=0, var_precio=igual} | 0.8482665 | 1884 |
| [14] | {a_reformar=0, vistas=1} | 0.8451148 | 1877 |
| [15] | {jardin=0, vistas=1, tipo_vendedor=2} | 0.8446646 | 1876 |
reglas_a=apriori(data2, parameter = list(supp = 0.05))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.8 0.1 1 none FALSE TRUE 5 0.05 1
## maxlen target ext
## 10 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 111
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[57 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [45 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.05)): Mining stopped (maxlen
## reached). Only patterns up to a length of 10 returned!
## done [3.10s].
## writing ... [2895636 rule(s)] done [0.89s].
## creating S4 object ... done [2.95s].
# Filtramos las más relevantes
filtro_a <- interestMeasure(reglas_a,
measure = "lift",
transactions = data2)
summary(filtro_a)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.8476 1.0048 1.0403 1.0878 1.1104 2.1050
# Se utiliza el mismo soporte para su comparación
reglas_e=eclat(data2, parameter = list(supp = 0.05))
## Eclat
##
## parameter specification:
## tidLists support minlen maxlen target ext
## FALSE 0.05 1 10 frequent itemsets TRUE
##
## algorithmic control:
## sparse sort verbose
## 7 -2 TRUE
##
## Absolute minimum support count: 111
##
## create itemset ...
## set transactions ...[57 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [45 item(s)] done [0.00s].
## creating bit matrix ... [45 row(s), 2221 column(s)] done [0.00s].
## writing ... [679789 set(s)] done [0.23s].
## Creating S4 object ... done [0.40s].
filtro_e <- interestMeasure(reglas_e,
measure = "lift",
transactions = data2)
summary(filtro_e)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.4603 0.9608 1.1878 1.6267 1.6754 29.8050
El algoritmo apriori realiza menor dispersión en los datos, lo que demuestra un mejor desempeño para este caso.
Para aquellas reglas que se cumplen en la mayor parte de los inmuebles, se utiliza un soporte alto. Tras varias pruebas, un soporte alto que posea un lift significativo, es decir, mayor o igual a 2, es de 0,1.
reglas1 = apriori(data2, parameter = list(supp = 0.1, conf = 0.8))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.8 0.1 1 none FALSE TRUE 5 0.1 1
## maxlen target ext
## 10 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 222
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[57 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [34 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.1, conf = 0.8)): Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
## done [0.78s].
## writing ... [793726 rule(s)] done [0.20s].
## creating S4 object ... done [0.47s].
Por el contrario, si se desea buscar casos más concretos, entonces se baja el soporte.
reglas2 = apriori(data2, parameter = list(supp = 0.025, conf = 0.8))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.8 0.1 1 none FALSE TRUE 5 0.025 1
## maxlen target ext
## 10 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 55
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[57 item(s), 2221 transaction(s)] done [0.00s].
## sorting and recoding items ... [53 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(data2, parameter = list(supp = 0.025, conf = 0.8)): Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
## done [6.83s].
## writing ... [7936434 rule(s)] done [2.32s].
## creating S4 object ... done [5.92s].
Para trabajar con un número más reducido de reglas, se ha descartado reglas redundantes, ya que cubre la misma cantidad información o menor que otra regla de la misma utilidad y relevancia.
nr1 = reglas1[!is.redundant(x =reglas1, measure = "confidence")]
nr1.sorted = arules::sort(nr1, by="lift", decreasing=T)
nr2 = reglas2[!is.redundant(x =reglas2, measure = "confidence")]
nr2.sorted = arules::sort(nr2, by="lift", decreasing=T)
El Test Exacto de Fisher es una medida de calidad utilizada para estudiar la posible asociación entre dos variables cualitativas.
fisher = interestMeasure(nr1.sorted, measure = c("fishersExactTest"),transactions = data2)
quality(nr1.sorted) = cbind(quality(nr1.sorted), fisher)
df1=as(nr1.sorted, Class = "data.frame")
kable(df1[1:8,])
| rules | support | confidence | coverage | lift | count | fisher | |
|---|---|---|---|---|---|---|---|
| 25677 | {ascensor=0,terraza=0,aire.acondicionado=0,balcon=0} => {armarios.empotrados=0} | 0.1004052 | 0.9330544 | 0.1076092 | 2.080636 | 223 | 0 |
| 92017 | {ascensor=0,acceso.adaptado=0,aire.acondicionado=0,balcon=0,trastero=0} => {armarios.empotrados=0} | 0.1017560 | 0.9040000 | 0.1125619 | 2.015847 | 226 | 0 |
| 89236 | {ascensor=0,terraza=0,aire.acondicionado=0,hab_cat=1-3,tipo_vendedor=2} => {baños_cat=1} | 0.1049077 | 0.8859316 | 0.1184151 | 2.009861 | 233 | 0 |
| 92032 | {ascensor=0,acceso.adaptado=0,aire.acondicionado=0,balcon=0,tipo_vendedor=2} => {armarios.empotrados=0} | 0.1017560 | 0.9003984 | 0.1130122 | 2.007816 | 226 | 0 |
| 89240 | {ascensor=0,terraza=0,aire.acondicionado=0,vistas=1,hab_cat=1-3} => {baños_cat=1} | 0.1004052 | 0.8849206 | 0.1134624 | 2.007568 | 223 | 0 |
| 24700 | {ascensor=0,terraza=0,aire.acondicionado=0,hab_cat=1-3} => {baños_cat=1} | 0.1062584 | 0.8838951 | 0.1202161 | 2.005241 | 236 | 0 |
| 92012 | {ascensor=0,acceso.adaptado=0,aire.acondicionado=0,balcon=0,garaje.incluido=0} => {armarios.empotrados=0} | 0.1035570 | 0.8984375 | 0.1152634 | 2.003443 | 230 | 0 |
| 24349 | {ascensor=0,armarios.empotrados=0,aire.acondicionado=0,hab_cat=1-3} => {baños_cat=1} | 0.1053579 | 0.8830189 | 0.1193156 | 2.003253 | 234 | 0 |
fisher <- interestMeasure(nr2.sorted, measure = c("fishersExactTest"),transactions = data2)
quality(nr2.sorted) <- cbind(quality(nr2.sorted), fisher)
df2=as(nr2.sorted, Class = "data.frame")
kable(df2[1:20,])
| rules | support | confidence | coverage | lift | count | fisher | |
|---|---|---|---|---|---|---|---|
| 274077 | {jardin=1,ascensor=1,terraza=1,var_precio=igual,tipo_vendedor=2} => {piscina=1} | 0.0252139 | 0.8000000 | 0.0315173 | 12.005405 | 56 | 0 |
| 70249 | {piscina=1,terraza=1,aire.acondicionado=1,baños_cat=+1} => {garaje.incluido=1} | 0.0252139 | 0.8484848 | 0.0297163 | 4.141725 | 56 | 0 |
| 13404 | {piscina=1,terraza=1,aire.acondicionado=1} => {garaje.incluido=1} | 0.0274651 | 0.8472222 | 0.0324178 | 4.135562 | 61 | 0 |
| 13405 | {piscina=1,terraza=1,armarios.empotrados=1} => {garaje.incluido=1} | 0.0256641 | 0.8260870 | 0.0310671 | 4.032394 | 57 | 0 |
| 285230 | {piscina=1,terraza=1,vistas=1,baños_cat=+1,tipo_vendedor=2} => {garaje.incluido=1} | 0.0292661 | 0.8227848 | 0.0355696 | 4.016275 | 65 | 0 |
| 70352 | {piscina=1,aire.acondicionado=1,baños_cat=+1,tipo_vendedor=2} => {garaje.incluido=1} | 0.0270149 | 0.8219178 | 0.0328681 | 4.012043 | 60 | 0 |
| 70413 | {piscina=1,armarios.empotrados=1,baños_cat=+1,tipo_vendedor=2} => {garaje.incluido=1} | 0.0256641 | 0.8142857 | 0.0315173 | 3.974788 | 57 | 0 |
| 70285 | {piscina=1,terraza=1,vistas=1,baños_cat=+1} => {garaje.incluido=1} | 0.0315173 | 0.8139535 | 0.0387213 | 3.973166 | 70 | 0 |
| 70322 | {piscina=1,terraza=1,vistas=1,tipo_vendedor=2} => {garaje.incluido=1} | 0.0315173 | 0.8139535 | 0.0387213 | 3.973166 | 70 | 0 |
| 13414 | {piscina=1,terraza=1,vistas=1} => {garaje.incluido=1} | 0.0351193 | 0.8125000 | 0.0432238 | 3.966071 | 78 | 0 |
| 13418 | {piscina=1,aire.acondicionado=1,baños_cat=+1} => {garaje.incluido=1} | 0.0297163 | 0.8048780 | 0.0369203 | 3.928866 | 66 | 0 |
| 13431 | {piscina=1,armarios.empotrados=1,baños_cat=+1} => {garaje.incluido=1} | 0.0288158 | 0.8000000 | 0.0360198 | 3.905055 | 64 | 0 |
| 2249253 | {terraza=0,distrito=poblats marítims,armarios.empotrados=0,acceso.adaptado=0,trastero=0,vistas=1,baños_cat=1} => {ascensor=0} | 0.0252139 | 0.8000000 | 0.0315173 | 3.314925 | 56 | 0 |
| 2249279 | {terraza=0,distrito=poblats marítims,armarios.empotrados=0,acceso.adaptado=0,vistas=1,baños_cat=1,tipo_vendedor=2} => {ascensor=0} | 0.0252139 | 0.8000000 | 0.0315173 | 3.314925 | 56 | 0 |
| 70248 | {piscina=1,aire.acondicionado=1,garaje.incluido=1,baños_cat=+1} => {terraza=1} | 0.0252139 | 0.8484848 | 0.0297163 | 2.967693 | 56 | 0 |
| 13408 | {piscina=1,balcon=0,garaje.incluido=1} => {terraza=1} | 0.0265646 | 0.8428571 | 0.0315173 | 2.948009 | 59 | 0 |
| 285220 | {piscina=1,garaje.incluido=1,baños_cat=+1,var_precio=igual,tipo_vendedor=2} => {terraza=1} | 0.0288158 | 0.8311688 | 0.0346691 | 2.907128 | 64 | 0 |
| 70281 | {piscina=1,garaje.incluido=1,baños_cat=+1,tipo_vendedor=2} => {terraza=1} | 0.0292661 | 0.8227848 | 0.0355696 | 2.877803 | 65 | 0 |
| 70602 | {piscina=1,aire.acondicionado=1,baños_cat=+1,tipo_vendedor=2} => {terraza=1} | 0.0270149 | 0.8219178 | 0.0328681 | 2.874771 | 60 | 0 |
| 70278 | {piscina=1,garaje.incluido=1,baños_cat=+1,var_precio=igual} => {terraza=1} | 0.0310671 | 0.8214286 | 0.0378208 | 2.873060 | 69 | 0 |
plot(nr1.sorted[1:100], method="paracoord", control=list(reorder=TRUE))
plot(nr2.sorted[1:100], method="paracoord", control=list(reorder=TRUE))
A continuación, se realiza, para este nuevo dataset, como los apartados anteriores. Ahora, se añade como consecuente la variable binaria que indica si el piso está vendido o no. Con la fianlidad de conocer que carácteristicas poseen las propiedades para que tengan mayor probabiblidad de ser vendidas. Y, por el contrario, observar cuáles son las que no se produzca la venta.
sum_ven=datosA%>%
group_by(vendido)%>%
summarize(support=n()/nrow(data1),support_count=n())
#Graficar
ggplot(data=sum_ven,aes(x=vendido,y=support, fill=vendido))+
geom_bar(stat='identity')+
coord_flip()+
theme_minimal()
# Categorizamos las variables
datosA$baños_cat=cut(datosA$ad_characteristics_bathNumber,breaks = c(0,1,10),labels=c("1","+1"),include.lowest = TRUE)
datosA$hab_cat=cut(datosA$ad_characteristics_roomNumber, breaks = c(0,3,10),labels=c("1-3","+3"),include.lowest = TRUE)
datosA$planta_cat=cut(datosA$planta, breaks = c(0, 2, 4,100),labels=c("Baja", "Media", "Alta"),include.lowest = TRUE)
datosA$var_precio=cut(datosA$variacion_precio,
breaks = c(-999999,-0.001,0.001,999999),
labels=c("baja",'igual',"sube"),
include.lowest = TRUE)
sub_datos1<-select(datosA,ad_characteristics_hasGarden,ad_characteristics_hasLift,ad_characteristics_hasParking,
ad_characteristics_hasSwimmingPool,ad_characteristics_hasTerrace,ad_condition_isGoodCondition,
ad_condition_isNeedsRenovating,ad_owner_type,distrito,planta_cat,vistas,vendido,baños_cat,
hab_cat,var_precio)
datosA1<-data.frame(lapply(sub_datos1,factor))
colnames(datosA1)<-c('jardin','ascensor','parking','piscina','terraza','buena_condicion','a_reformar','tipo_vendedor',
'distrito','planta_cat','vistas','vendido','baños_cat','hab_cat','var_precio')
datosA1 <- as(datosA1, "transactions")
reglasA = apriori(datosA1, parameter = list(supp = 0.003, conf = 0.8),
appearance = list(rhs=c("vendido=1")))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.8 0.1 1 none FALSE TRUE 5 0.003 1
## maxlen target ext
## 10 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 19
##
## set item appearances ...[1 item(s)] done [0.00s].
## set transactions ...[50 item(s), 6520 transaction(s)] done [0.01s].
## sorting and recoding items ... [50 item(s)] done [0.00s].
## creating transaction tree ... done [0.01s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10
## Warning in apriori(datosA1, parameter = list(supp = 0.003, conf = 0.8), : Mining
## stopped (maxlen reached). Only patterns up to a length of 10 returned!
## done [1.59s].
## writing ... [12 rule(s)] done [0.06s].
## creating S4 object ... done [0.04s].
nra = reglasA[!is.redundant(x =reglasA, measure = "confidence")]
nra.sorted = arules::sort(nra, by="lift", decreasing=T)
fisher = interestMeasure(nra, measure = c("fishersExactTest"),transactions = datosA1)
quality(nra.sorted) = cbind(quality(nra.sorted), fisher)
dfA=as(nra.sorted, Class = "data.frame")
# Eliminamos p-valor >=0.05
dfA<-dfA[which(dfA$fisher<0.05),]
kable(dfA[1:4,])
| rules | support | confidence | coverage | lift | count | fisher | |
|---|---|---|---|---|---|---|---|
| 8 | {buena_condicion=0,tipo_vendedor=2,distrito=la saïdia,hab_cat=1-3,var_precio=igual} => {vendido=1} | 0.0035276 | 0.8518519 | 0.0041411 | 2.310347 | 23 | 7.00e-07 |
| 1 | {ascensor=1,buena_condicion=0,distrito=la saïdia,hab_cat=1-3} => {vendido=1} | 0.0033742 | 0.8461538 | 0.0039877 | 2.294893 | 22 | 1.10e-06 |
| 5 | {parking=0,distrito=quatre carreres,planta_cat=Media,baños_cat=1} => {vendido=1} | 0.0030675 | 0.8333333 | 0.0036810 | 2.260122 | 20 | 1.10e-06 |
| 2 | {buena_condicion=0,distrito=la saïdia,hab_cat=1-3,var_precio=igual} => {vendido=1} | 0.0035276 | 0.8214286 | 0.0042945 | 2.227835 | 23 | 1.28e-05 |
descVend2 = data.frame("variable" = colnames(dataCluster),
"tipo" = c(rep("numerical", 1), rep("binary", 4), "numerical", rep("binary", 9), "numerical", "binary"))
rownames(descVend2) = descVend2$variable
dataCluster[which(descVend2$tipo == 'binary')] = lapply(dataCluster[which(descVend2$tipo == 'binary')], as.factor)
Cuando se dispone de un conjunto de datos mixto, es decir, un conjunto de individuos sobre los que se han observado tanto variables cuantitativas como cualitativas (o categóricas), la distancia de Gower es la apropiada.
gower_dist = daisy(dataCluster, metric = "gower", type = list(logratio = 3))
gower_mat = as.matrix(gower_dist)
Para estudiar la tendencia de agrupamiento de los datos, utilizaremos un mapa de calor. Descartamos el uso del estadístico de Hopkins porque está programado para la distancia euclídea y no para la de Gower. Como se puede ver en el mapa de calor, a simple vista, parece haber 6 u 8 clusters.
En primer lugar, los métodos que se van a utilizar son jerárquicos: Ward, Media, Centroide y Mediana. La elección de los métodos no es aleatoria, sino que los tres primeros se han escogido por ser los más comunes y el de la Mediana, por ser un estadístico robusto (en comparación con la media)
cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between","wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
row.clust[i] <- paste("Cluster-", i, " size")
}
for(i in c(2:k)){
stats.names[i] <- paste("Test", i-1)
for(j in seq_along(clust.assess)){
output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
}
for(d in 1:k) {
cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
cluster.sizes[d, i]
}
}
output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
ward_clust = hclust(gower_dist, method="ward.D2")
average_clust = hclust(gower_dist, method="average")
median_clust = hclust(gower_dist, method="median")
centroid_clust = hclust(gower_dist, method="centroid")
stats_ward = cstats.table(gower_dist, ward_clust, 10)
stats_average = cstats.table(gower_dist, average_clust, 10)
stats_median = cstats.table(gower_dist, median_clust, 10)
stats_centroid = cstats.table(gower_dist, centroid_clust, 10)
Tras obervar los gráficos de SS y el coeficiente de Silhoutte, el número de clusters elegidos es 6, porque tiene el mismo coeficiente de Silhoutte que con 4 y 5 clusters. Sin embargo, la suma de cuadrados intracluster es más pequeña.
El número de pisos en cada cluster es el siguiente:
## ward_groups
## 1 2 3 4 5 6
## 632 280 397 275 493 285
El resumen estasístico del método de Ward es:
| Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 | Test 7 | Test 8 | Test 9 | |
|---|---|---|---|---|---|---|---|---|---|
| cluster.number | 2.00 | 3.00 | 4.00 | 5.00 | 6.00 | 7.00 | 8.00 | 9.00 | 10.00 |
| n | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 |
| within.cluster.ss | 86.58 | 76.25 | 69.72 | 64.56 | 59.54 | 56.71 | 54.04 | 51.63 | 49.36 |
| average.within | 0.25 | 0.23 | 0.22 | 0.21 | 0.20 | 0.20 | 0.19 | 0.18 | 0.18 |
| average.between | 0.31 | 0.32 | 0.30 | 0.30 | 0.30 | 0.30 | 0.29 | 0.29 | 0.29 |
| wb.ratio | 0.80 | 0.74 | 0.72 | 0.70 | 0.67 | 0.66 | 0.64 | 0.63 | 0.61 |
| dunn2 | 1.17 | 0.99 | 0.89 | 0.84 | 0.84 | 0.84 | 0.70 | 0.72 | 0.72 |
| avg.silwidth | 0.19 | 0.16 | 0.14 | 0.14 | 0.14 | 0.13 | 0.12 | 0.13 | 0.12 |
| Cluster- 1 size | 1197.00 | 917.00 | 917.00 | 917.00 | 632.00 | 199.00 | 199.00 | 199.00 | 199.00 |
| Cluster- 2 size | 1165.00 | 280.00 | 280.00 | 280.00 | 280.00 | 433.00 | 433.00 | 433.00 | 168.00 |
| Cluster- 3 size | 0.00 | 1165.00 | 672.00 | 397.00 | 397.00 | 280.00 | 280.00 | 156.00 | 156.00 |
| Cluster- 4 size | 0.00 | 0.00 | 493.00 | 275.00 | 275.00 | 397.00 | 397.00 | 397.00 | 397.00 |
| Cluster- 5 size | 0.00 | 0.00 | 0.00 | 493.00 | 493.00 | 275.00 | 275.00 | 275.00 | 275.00 |
| Cluster- 6 size | 0.00 | 0.00 | 0.00 | 0.00 | 285.00 | 493.00 | 249.00 | 249.00 | 249.00 |
| Cluster- 7 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 285.00 | 285.00 | 124.00 | 265.00 |
| Cluster- 8 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 244.00 | 285.00 | 124.00 |
| Cluster- 9 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 244.00 | 285.00 |
| Cluster- 10 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 244.00 |
Tras obervar los gráficos de SS y el coeficiente de Silhoutte, el número de clusters elegidos es 4. A pesar de ello, es indiferente que el número de clusters sea 4,5 o 6, ya que este método forma un cluster con la mayoría de pisos (en torno a 2000) y el resto de clusters con menos de 200 pisos (e incluso menos de 50).
El número de pisos en cada cluster es el siguiente:
## average_groups
## 1 2 3 4
## 2044 237 68 13
El resumen estadístico de este método es:
| Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 | Test 7 | Test 8 | Test 9 | |
|---|---|---|---|---|---|---|---|---|---|
| cluster.number | 2.00 | 3.00 | 4.00 | 5.00 | 6.00 | 7.00 | 8.00 | 9.00 | 10.00 |
| n | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 |
| within.cluster.ss | 107.15 | 91.13 | 86.93 | 86.42 | 86.12 | 85.46 | 85.20 | 84.60 | 81.78 |
| average.within | 0.28 | 0.26 | 0.25 | 0.25 | 0.25 | 0.25 | 0.25 | 0.25 | 0.24 |
| average.between | 0.39 | 0.38 | 0.38 | 0.38 | 0.38 | 0.37 | 0.37 | 0.37 | 0.37 |
| wb.ratio | 0.71 | 0.68 | 0.67 | 0.67 | 0.67 | 0.67 | 0.67 | 0.67 | 0.66 |
| dunn2 | 1.41 | 1.36 | 1.25 | 1.28 | 1.27 | 1.25 | 1.24 | 1.25 | 1.28 |
| avg.silwidth | 0.28 | 0.23 | 0.20 | 0.18 | 0.16 | 0.13 | 0.11 | 0.11 | 0.10 |
| Cluster- 1 size | 2349.00 | 2112.00 | 2044.00 | 2044.00 | 2044.00 | 2035.00 | 2035.00 | 2035.00 | 2035.00 |
| Cluster- 2 size | 13.00 | 237.00 | 237.00 | 228.00 | 228.00 | 228.00 | 228.00 | 216.00 | 103.00 |
| Cluster- 3 size | 0.00 | 13.00 | 68.00 | 68.00 | 64.00 | 64.00 | 64.00 | 64.00 | 64.00 |
| Cluster- 4 size | 0.00 | 0.00 | 13.00 | 13.00 | 13.00 | 13.00 | 5.00 | 5.00 | 5.00 |
| Cluster- 5 size | 0.00 | 0.00 | 0.00 | 9.00 | 9.00 | 9.00 | 9.00 | 12.00 | 113.00 |
| Cluster- 6 size | 0.00 | 0.00 | 0.00 | 0.00 | 4.00 | 9.00 | 9.00 | 9.00 | 12.00 |
| Cluster- 7 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 4.00 | 4.00 | 9.00 | 9.00 |
| Cluster- 8 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 8.00 | 4.00 | 9.00 |
| Cluster- 9 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 8.00 | 4.00 |
| Cluster- 10 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 8.00 |
Al igual que ha ocurrido con el método de la media, este método tampoco separa “correctamente” los clusters. Da igual escoger una k de 3,4 o 5 porque el primer cluster tiene prácticamente todos los pisos y el resto de clusters, 1, 2 o 3. Los gráficos del coeficiente de Silhoutte y de la SS se encuentran son:
El número de pisos en cada cluster es el siguiente:
## centroid_groups
## 1 2 3 4 5
## 2353 3 3 2 1
El resumen estadístico del método del Centroide es:
| Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 | Test 7 | Test 8 | Test 9 | |
|---|---|---|---|---|---|---|---|---|---|
| cluster.number | 2.00 | 3.00 | 4.00 | 5.00 | 6.00 | 7.00 | 8.00 | 9.00 | 10.00 |
| n | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 |
| within.cluster.ss | 108.02 | 107.75 | 107.24 | 106.75 | 106.64 | 106.55 | 106.52 | 106.50 | 106.42 |
| average.within | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 |
| average.between | 0.44 | 0.42 | 0.45 | 0.45 | 0.44 | 0.44 | 0.44 | 0.44 | 0.43 |
| wb.ratio | 0.64 | 0.66 | 0.63 | 0.62 | 0.63 | 0.64 | 0.64 | 0.64 | 0.65 |
| dunn2 | 1.56 | 1.49 | 1.49 | 1.36 | 1.27 | 1.26 | 0.86 | 0.72 | 0.72 |
| avg.silwidth | 0.34 | 0.25 | 0.20 | 0.18 | 0.12 | 0.04 | 0.03 | 0.02 | -0.04 |
| Cluster- 1 size | 2361.00 | 2359.00 | 2356.00 | 2353.00 | 2352.00 | 2351.00 | 2351.00 | 2351.00 | 2350.00 |
| Cluster- 2 size | 1.00 | 2.00 | 3.00 | 3.00 | 3.00 | 3.00 | 3.00 | 3.00 | 3.00 |
| Cluster- 3 size | 0.00 | 1.00 | 2.00 | 3.00 | 3.00 | 3.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 4 size | 0.00 | 0.00 | 1.00 | 2.00 | 2.00 | 2.00 | 2.00 | 1.00 | 1.00 |
| Cluster- 5 size | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 | 2.00 | 2.00 | 2.00 |
| Cluster- 6 size | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 7 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 8 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 9 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 |
| Cluster- 10 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 |
Del mismo modo que con los dos métodos anteriores ocurre con el método de la mediana. Además, como se puede observar en el gráfico del coeficiente de Silhoutte, sólo con k=2 o k=3 es positivo.
Aun con este número de clusters, vemos cómo el patrón se repite: el primer cluster con la mayoría de pisos y el resto con 1 o 5 pisos.
## median_groups
## 1 2 3
## 2356 5 1
El resumen estadístico de este método es:
| Test 1 | Test 2 | Test 3 | Test 4 | Test 5 | Test 6 | Test 7 | Test 8 | Test 9 | |
|---|---|---|---|---|---|---|---|---|---|
| cluster.number | 2.00 | 3.00 | 4.00 | 5.00 | 6.00 | 7.00 | 8.00 | 9.00 | 10.00 |
| n | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 | 2362.00 |
| within.cluster.ss | 108.05 | 107.33 | 107.16 | 106.70 | 106.51 | 106.48 | 106.42 | 106.37 | 106.31 |
| average.within | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 | 0.28 |
| average.between | 0.40 | 0.45 | 0.39 | 0.38 | 0.38 | 0.38 | 0.38 | 0.38 | 0.38 |
| wb.ratio | 0.70 | 0.63 | 0.72 | 0.73 | 0.73 | 0.73 | 0.73 | 0.73 | 0.73 |
| dunn2 | 1.43 | 1.44 | 1.06 | 1.03 | 1.06 | 0.89 | 0.89 | 0.89 | 0.89 |
| avg.silwidth | 0.28 | 0.23 | -0.01 | -0.06 | -0.09 | -0.15 | -0.17 | -0.19 | -0.19 |
| Cluster- 1 size | 2361.00 | 2356.00 | 2352.00 | 2345.00 | 2345.00 | 2345.00 | 2345.00 | 2345.00 | 2345.00 |
| Cluster- 2 size | 1.00 | 5.00 | 4.00 | 7.00 | 5.00 | 5.00 | 4.00 | 4.00 | 4.00 |
| Cluster- 3 size | 0.00 | 1.00 | 5.00 | 4.00 | 4.00 | 4.00 | 4.00 | 4.00 | 4.00 |
| Cluster- 4 size | 0.00 | 0.00 | 1.00 | 5.00 | 2.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 5 size | 0.00 | 0.00 | 0.00 | 1.00 | 5.00 | 5.00 | 5.00 | 4.00 | 2.00 |
| Cluster- 6 size | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 | 1.00 | 2.00 |
| Cluster- 7 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 8 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 | 1.00 |
| Cluster- 9 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 |
| Cluster- 10 size | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 |
El método de K-medoides, en comparación con el método de K-medias, es mucho más robusto, puesto que, los medoides son mejores representantes de los clusters que los centroides.
dataCluster[which(gower_mat == min(gower_mat[gower_mat != min(gower_mat)]), arr.ind = TRUE)[1, ], ]
## baños jardin ascensor piscina terraza habitaciones a_reformar tipo_vendedor
## 572 2 0 1 0 0 3 0 2
## 59 2 0 1 0 0 3 0 2
## armarios.empotrados acceso.adaptado aire.acondicionado balcon trastero
## 572 1 0 1 1 0
## 59 1 0 1 1 0
## garaje.incluido calefaccion planta vistas
## 572 0 1 7 1
## 59 0 1 8 1
sil_width = c(NA)
for(i in 2:10){
pam_fit = pam(gower_dist, diss = TRUE, k = i)
sil_width[i] = pam_fit$silinfo$avg.width
}
Como podemos observar en el gráfico del coeficiente de Silhoutte, el número de clusters elegido es 6, porque tiene un coeficiente más alto que con k=5 y k=7
k = 6
pam_fit = pam(gower_dist, diss = TRUE, k)
Tras ver todos los métodos, descartamos el método de la media, de la mediana y del centroide. Ahora, nos toca seleccionar entre el método de Ward y K-Medoides:
El método final seleccionado es el método K-Medoides porque tiene un mayor coeficiente de silhoutte medio. Además, tiene menas observaciones mal clasificadas (negativos).
clust = pam_fit$clustering
dist = vend$distrito
data = data.frame(clust, dist)
tsne_object <- Rtsne(gower_dist, is_distance = TRUE, dims = 3)
tsne_df <- tsne_object$Y %>%
data.frame() %>%
setNames(c("X", "Y", "Z")) %>%
mutate(cluster = factor(pam_fit$clustering))
plot_ly(x=tsne_df$X, y=tsne_df$Y, z=tsne_df$Z, size = I(15), type="scatter3d", mode="markers", color=tsne_df$cluster)
plot_ly(x=tsne_df$X, y=tsne_df$Y, size = I(15), type="scatter", mode="markers", color=tsne_df$cluster)
Por último, haremos un estudio más detallado para ver si hay clusters en los que predomina algún distrito.
pam_results = dataCluster %>%
mutate(cluster = pam_fit$clustering) %>%
group_by(cluster) %>%
do(the_summary = summary(.))
| 1 | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|
| algirós | 26 | 11 | 6 | 17 | 4 | 0 |
| benicalap | 11 | 9 | 5 | 25 | 34 | 21 |
| benimaclet | 6 | 5 | 4 | 2 | 9 | 0 |
| camins al grau | 24 | 19 | 10 | 20 | 14 | 5 |
| campanar | 18 | 15 | 8 | 15 | 8 | 39 |
| ciutat vella | 74 | 74 | 27 | 34 | 22 | 3 |
| el pla del real | 23 | 32 | 14 | 7 | 1 | 8 |
| extramurs | 39 | 57 | 19 | 35 | 15 | 6 |
| jesús | 38 | 11 | 11 | 31 | 30 | 2 |
| l’eixample | 69 | 69 | 28 | 38 | 14 | 7 |
| l’olivereta | 15 | 16 | 12 | 27 | 34 | 0 |
| la saïdia | 23 | 17 | 10 | 36 | 29 | 1 |
| patraix | 51 | 30 | 21 | 39 | 18 | 1 |
| poblats marítims | 56 | 60 | 25 | 56 | 98 | 17 |
| pobles de l’oest | 3 | 5 | 1 | 5 | 10 | 2 |
| pobles del nord | 0 | 0 | 1 | 3 | 1 | 1 |
| pobles del sud | 8 | 10 | 8 | 17 | 20 | 10 |
| quatre carreres | 42 | 31 | 12 | 42 | 33 | 18 |
| rascanya | 30 | 9 | 12 | 46 | 50 | 12 |
pam_results$the_summary[[1]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.00 0:541 0: 81 0:543 0:491 Min. :1.000 0:509
## 1st Qu.:1.00 1: 15 1:475 1: 13 1: 65 1st Qu.:3.000 1: 47
## Median :2.00 Median :3.000
## Mean :1.75 Mean :3.165
## 3rd Qu.:2.00 3rd Qu.:4.000
## Max. :8.00 Max. :8.000
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 29 0:105 0:459 0: 82 0: 0
## 2:527 1:451 1: 97 1:474 1:556
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0:471 0:425 0:177 Min. : 0.000 0: 24 Min. :1
## 1: 85 1:131 1:379 1st Qu.: 2.000 1:532 1st Qu.:1
## Median : 4.000 Median :1
## Mean : 3.892 Mean :1
## 3rd Qu.: 5.000 3rd Qu.:1
## Max. :17.000 Max. :1
clust1 = data[data$clust==1, ]
ggplot(data = clust1, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 1")
num1 = table(clust1$dist)
perc1 = 100*num1/sum(num1)
kable(cbind(num1, perc1))
| num1 | perc1 | |
|---|---|---|
| algirós | 26 | 4.6762590 |
| benicalap | 11 | 1.9784173 |
| benimaclet | 6 | 1.0791367 |
| camins al grau | 24 | 4.3165468 |
| campanar | 18 | 3.2374101 |
| ciutat vella | 74 | 13.3093525 |
| el pla del real | 23 | 4.1366906 |
| extramurs | 39 | 7.0143885 |
| jesús | 38 | 6.8345324 |
| l’eixample | 69 | 12.4100719 |
| l’olivereta | 15 | 2.6978417 |
| la saïdia | 23 | 4.1366906 |
| patraix | 51 | 9.1726619 |
| poblats marítims | 56 | 10.0719424 |
| pobles de l’oest | 3 | 0.5395683 |
| pobles del nord | 0 | 0.0000000 |
| pobles del sud | 8 | 1.4388489 |
| quatre carreres | 42 | 7.5539568 |
| rascanya | 30 | 5.3956835 |
El cluster 1 está formado por 556 pisos con una media de 1,75 baños y 3,165 habitaciones y con ascensor (85,43%), armarios empotrados (81,11%), aire acondicionado (85,35%), balcón (100%) y sin jardín (97,30%), ni piscina (97,66%), ni terraza (88,31%), ni adaptados a personas con movilidad reducida (82,55%), ni garaje incluido (76,43%), ni trastero (84,71%). Generalmente estos pisos tienen una altura “mediana” (con una media de 3.892) y son exteriores (95,6%).
Como se puede observar, el peso del balcón es muy grande. Los pisos que tienen estas características (incluido balcón) se encuentran desperdigados por toda Valencia (Ciutat Vella en un 13,31%, L’Eixample en un 12,41% y Poblats Marítims en un 10,07%).
pam_results$the_summary[[2]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.00 0:469 0: 44 0:467 0:327 Min. :1.00 0:445
## 1st Qu.:1.00 1: 11 1:436 1: 13 1:153 1st Qu.:2.00 1: 35
## Median :2.00 Median :3.00
## Mean :1.85 Mean :3.04
## 3rd Qu.:2.00 3rd Qu.:4.00
## Max. :5.00 Max. :8.00
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 24 0: 94 0:363 0: 55 0:480
## 2:456 1:386 1:117 1:425 1: 0
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0:417 0:381 0: 85 Min. : 0.00 0: 29 Min. :2
## 1: 63 1: 99 1:395 1st Qu.: 1.00 1:451 1st Qu.:2
## Median : 3.00 Median :2
## Mean : 3.56 Mean :2
## 3rd Qu.: 5.00 3rd Qu.:2
## Max. :18.00 Max. :2
clust2 = data[data$clust==2, ]
ggplot(data = clust2, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 2")
num2 = table(clust2$dist)
perc2 = 100*num2/sum(num2)
kable(cbind(num2, perc2))
| num2 | perc2 | |
|---|---|---|
| algirós | 11 | 2.291667 |
| benicalap | 9 | 1.875000 |
| benimaclet | 5 | 1.041667 |
| camins al grau | 19 | 3.958333 |
| campanar | 15 | 3.125000 |
| ciutat vella | 74 | 15.416667 |
| el pla del real | 32 | 6.666667 |
| extramurs | 57 | 11.875000 |
| jesús | 11 | 2.291667 |
| l’eixample | 69 | 14.375000 |
| l’olivereta | 16 | 3.333333 |
| la saïdia | 17 | 3.541667 |
| patraix | 30 | 6.250000 |
| poblats marítims | 60 | 12.500000 |
| pobles de l’oest | 5 | 1.041667 |
| pobles del nord | 0 | 0.000000 |
| pobles del sud | 10 | 2.083333 |
| quatre carreres | 31 | 6.458333 |
| rascanya | 9 | 1.875000 |
El cluster 2 está formado por 480 pisos con una media de 1,85 baños y 3 habitaciones y con ascensor (90,83%), armarios empotrados (80,41%), aire acondicionado (88,54%), calefacción (82,29%) y sin jardín (97,70%), ni piscina (97,29%), ni terraza (68,12%), ni adaptados a personas con movilidad reducida (75,62%), ni balcón (0%), ni trastero (86,87%). Generalmente estos pisos tienen una altura “mediana” (con una media de 3.56) y son exteriores (93,96%).
Como se puede observar de nuevo, el peso del balcón es muy grande. Los pisos que tienen estas características (sin balcón) se encuentran desperdigados por toda Valencia (Ciutat Vella en un 15,42%, L’Eixample en un 14,38%, Extramurs en un 11,88% y Poblats Marítims en un 12,50%).
pam_results$the_summary[[3]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.000 0:229 0: 25 0:228 0: 58 Min. :1.000 0:195
## 1st Qu.:1.000 1: 5 1:209 1: 6 1:176 1st Qu.:3.000 1: 39
## Median :2.000 Median :3.000
## Mean :1.885 Mean :3.462
## 3rd Qu.:2.000 3rd Qu.:4.000
## Max. :5.000 Max. :8.000
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 21 0: 53 0: 34 0:154 0: 50
## 2:213 1:181 1:200 1: 80 1:184
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0:196 0:176 0: 51 Min. : 0.000 0: 11 Min. :3
## 1: 38 1: 58 1:183 1st Qu.: 2.000 1:223 1st Qu.:3
## Median : 4.000 Median :3
## Mean : 3.983 Mean :3
## 3rd Qu.: 6.000 3rd Qu.:3
## Max. :18.000 Max. :3
clust3 = data[data$clust==3, ]
ggplot(data = clust3, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 3")
num3 = table(clust3$dist)
perc3 = 100*num3/sum(num3)
kable(cbind(num3, perc3))
| num3 | perc3 | |
|---|---|---|
| algirós | 6 | 2.5641026 |
| benicalap | 5 | 2.1367521 |
| benimaclet | 4 | 1.7094017 |
| camins al grau | 10 | 4.2735043 |
| campanar | 8 | 3.4188034 |
| ciutat vella | 27 | 11.5384615 |
| el pla del real | 14 | 5.9829060 |
| extramurs | 19 | 8.1196581 |
| jesús | 11 | 4.7008547 |
| l’eixample | 28 | 11.9658120 |
| l’olivereta | 12 | 5.1282051 |
| la saïdia | 10 | 4.2735043 |
| patraix | 21 | 8.9743590 |
| poblats marítims | 25 | 10.6837607 |
| pobles de l’oest | 1 | 0.4273504 |
| pobles del nord | 1 | 0.4273504 |
| pobles del sud | 8 | 3.4188034 |
| quatre carreres | 12 | 5.1282051 |
| rascanya | 12 | 5.1282051 |
El cluster 3 está formado por 234 pisos con una media de 1,885 baños y 3,462 habitaciones y con ascensor (89,32%), terraza (75,21%), armarios empotrados (77,35%), adaptados a personas con movilidad reducida (85,47%), balcón (78,63%), calefacción (78,21%) y sin jardín (97,86%), ni piscina (97,44%), ni aire acondicionado (65,81%), ni trastero (83,76%), ni garaje (75,21%). Generalmente los pisos tienen una altura “mediana” (con una media de 3,98) y son exteriores (95,30%).
En este cluster, se encuentran pisos adecuados para personas con movilidad reducida, ya que además de estar adaptados, la mayoría cuenta con ascensor. Estos pisos están localizados, de nuevo, por toda la ciudad (Ciutat Vella en un 11,54%, L’Eixample en un 11,97% y Poblats Marítims en un 10,68%).
pam_results$the_summary[[4]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.000 0:475 0: 0 0:467 0:381 Min. :1.00 0:422
## 1st Qu.:1.000 1: 20 1:495 1: 28 1:114 1st Qu.:3.00 1: 73
## Median :2.000 Median :3.00
## Mean :1.628 Mean :3.17
## 3rd Qu.:2.000 3rd Qu.:4.00
## Max. :6.000 Max. :9.00
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 25 0:411 0:437 0:417 0:368
## 2:470 1: 84 1: 58 1: 78 1:127
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0:449 0:421 0:405 Min. : 0.00 0: 26 Min. :4
## 1: 46 1: 74 1: 90 1st Qu.: 2.00 1:469 1st Qu.:4
## Median : 3.00 Median :4
## Mean : 3.36 Mean :4
## 3rd Qu.: 4.00 3rd Qu.:4
## Max. :18.00 Max. :4
clust4 = data[data$clust==4, ]
ggplot(data = clust4, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 4")
num4 = table(clust4$dist)
perc4 = 100*num4/sum(num4)
kable(cbind(num4, perc4))
| num4 | perc4 | |
|---|---|---|
| algirós | 17 | 3.4343434 |
| benicalap | 25 | 5.0505051 |
| benimaclet | 2 | 0.4040404 |
| camins al grau | 20 | 4.0404040 |
| campanar | 15 | 3.0303030 |
| ciutat vella | 34 | 6.8686869 |
| el pla del real | 7 | 1.4141414 |
| extramurs | 35 | 7.0707071 |
| jesús | 31 | 6.2626263 |
| l’eixample | 38 | 7.6767677 |
| l’olivereta | 27 | 5.4545455 |
| la saïdia | 36 | 7.2727273 |
| patraix | 39 | 7.8787879 |
| poblats marítims | 56 | 11.3131313 |
| pobles de l’oest | 5 | 1.0101010 |
| pobles del nord | 3 | 0.6060606 |
| pobles del sud | 17 | 3.4343434 |
| quatre carreres | 42 | 8.4848485 |
| rascanya | 46 | 9.2929293 |
El cluster 4 está formado por 495 pisos con una media de 1,628 baños y 3,17 habitaciones y con únicamente ascensor (100%). En su mayoría, ninguno dispone de jardín (95,96%), ni piscina (94,34%), ni terraza (76,97%), ni armarios empotrados (83,03%), ni aire acondicionado (84,24%), ni balcón (74,34%), ni trastero (90,71%), ni garaje incluido (85,05%), ni calefacción (95,05%). Generalmente los pisos tienen una altura “mediana” (con una media de 3,36) y son exteriores (94,75%).
Como se puede observar, los pisos de este cluster, aunque tienen ascensor, parece que son “básicos”. Probablemente, sean los pisos más baratos de la ciudad. Estas observaciones se encuentran por toda Valencia.
pam_results$the_summary[[5]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.000 0:434 0:444 0:443 0:367 Min. : 1.000 0:367
## 1st Qu.:1.000 1: 10 1: 0 1: 1 1: 77 1st Qu.: 2.000 1: 77
## Median :1.000 Median : 3.000
## Mean :1.196 Mean : 2.721
## 3rd Qu.:1.000 3rd Qu.: 3.000
## Max. :5.000 Max. :12.000
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 14 0:379 0:426 0:376 0:350
## 2:430 1: 65 1: 18 1: 68 1: 94
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0:423 0:436 0:302 Min. :0.000 0: 20 Min. :5
## 1: 21 1: 8 1:142 1st Qu.:1.000 1:424 1st Qu.:5
## Median :3.000 Median :5
## Mean :2.655 Mean :5
## 3rd Qu.:4.000 3rd Qu.:5
## Max. :7.000 Max. :5
clust5 = data[data$clust==5, ]
ggplot(data = clust5, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 5")
num5 = table(clust5$dist)
perc5 = 100*num5/sum(num5)
kable(cbind(num5, perc5))
| num5 | perc5 | |
|---|---|---|
| algirós | 4 | 0.9009009 |
| benicalap | 34 | 7.6576577 |
| benimaclet | 9 | 2.0270270 |
| camins al grau | 14 | 3.1531532 |
| campanar | 8 | 1.8018018 |
| ciutat vella | 22 | 4.9549550 |
| el pla del real | 1 | 0.2252252 |
| extramurs | 15 | 3.3783784 |
| jesús | 30 | 6.7567568 |
| l’eixample | 14 | 3.1531532 |
| l’olivereta | 34 | 7.6576577 |
| la saïdia | 29 | 6.5315315 |
| patraix | 18 | 4.0540541 |
| poblats marítims | 98 | 22.0720721 |
| pobles de l’oest | 10 | 2.2522523 |
| pobles del nord | 1 | 0.2252252 |
| pobles del sud | 20 | 4.5045045 |
| quatre carreres | 33 | 7.4324324 |
| rascanya | 50 | 11.2612613 |
El cluster 5 está formado por 444 pisos con una media de 1,196 baños y 2,721 habitaciones y sin ningún equipamiento adicional. Generalmente, los pisos tienen una altura “baja” (con una media de 2,655) y son exteriores (95,49%).
Como se puede observar, los pisos de este cluster se encuentran principalmente en Poblats Marítims (22,07%). Probablemente, sean los pisos más baratos de la ciudad.
pam_results$the_summary[[6]]
## baños jardin ascensor piscina terraza habitaciones a_reformar
## Min. :1.000 0: 47 0: 24 0: 41 0: 22 Min. :1.000 0:150
## 1st Qu.:2.000 1:106 1:129 1:112 1:131 1st Qu.:3.000 1: 3
## Median :2.000 Median :3.000
## Mean :2.464 Mean :3.431
## 3rd Qu.:3.000 3rd Qu.:4.000
## Max. :6.000 Max. :8.000
## tipo_vendedor armarios.empotrados acceso.adaptado aire.acondicionado balcon
## 1: 18 0: 20 0:97 0: 22 0:114
## 2:135 1:133 1:56 1:131 1: 39
##
##
##
##
## trastero garaje.incluido calefaccion planta vistas cluster
## 0: 46 0: 22 0: 44 Min. : 0.000 0: 1 Min. :6
## 1:107 1:131 1:109 1st Qu.: 2.000 1:152 1st Qu.:6
## Median : 3.000 Median :6
## Mean : 4.549 Mean :6
## 3rd Qu.: 7.000 3rd Qu.:6
## Max. :17.000 Max. :6
clust6 = data[data$clust==6, ]
ggplot(data = clust6, aes(x = dist)) + geom_bar() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + labs(title = "Cluster 6")
num6 = table(clust6$dist)
perc6 = 100*num6/sum(num6)
kable(cbind(num6, perc6))
| num6 | perc6 | |
|---|---|---|
| algirós | 0 | 0.0000000 |
| benicalap | 21 | 13.7254902 |
| benimaclet | 0 | 0.0000000 |
| camins al grau | 5 | 3.2679739 |
| campanar | 39 | 25.4901961 |
| ciutat vella | 3 | 1.9607843 |
| el pla del real | 8 | 5.2287582 |
| extramurs | 6 | 3.9215686 |
| jesús | 2 | 1.3071895 |
| l’eixample | 7 | 4.5751634 |
| l’olivereta | 0 | 0.0000000 |
| la saïdia | 1 | 0.6535948 |
| patraix | 1 | 0.6535948 |
| poblats marítims | 17 | 11.1111111 |
| pobles de l’oest | 2 | 1.3071895 |
| pobles del nord | 1 | 0.6535948 |
| pobles del sud | 10 | 6.5359477 |
| quatre carreres | 18 | 11.7647059 |
| rascanya | 12 | 7.8431373 |
El cluster 6 está formado por 153 pisos con una media de 2,464 baños y 3,431 habitaciones, con jardín (69,28%), ascensor (84,31%), piscina (73,20%), terraza (85,62%), armarios empotrados (86,93%), aire acondicionado (85,62%), trastero (69,93%), garaje incluido (85,62%) y calefacción (71,24%) y sin balcón (74,51%).
Como se puede observar, los pisos de este clusters son los que más “equipamiento” tienen. Se caracterizan principalmente por tener piscina y encontrarse en Campanar (25,49%). Estos pisos tienen una altura “mediana-alta” (con una media de 4,549) y son en su totalidad exteriores (99,34%).